/*
 * tcp_server.cpp
 *
 *  Created on: 2008-11-27
 *      Author: fanliangliang
 */

#include "tcp_server.h"
#include "tcp_socket.h"
#include "socket_exception.h"

BEGIN_NAMESPACE_TOXIC

TcpServer::TcpServer()
:_descriptor(0)
,_isListening(false) {
	_descriptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (_descriptor < 0) {
		throw SocketException();
	}
}

TcpServer::~TcpServer() {
	close();
}

void TcpServer::close() {
	if (_descriptor != 0) {
		::closesocket(_descriptor);
		_descriptor = 0;
	}
}

void TcpServer::listen(const IpAddress& address, uint16_t port) {
	listen(SocketAddress(address, port));
}

void TcpServer::listen(const SocketAddress& address) {
	if (!_isListening) {
		if (::bind(_descriptor, address, SocketAddress::size()) != 0) {
			throw SocketException();
		}
		if (::listen(_descriptor, BACK_LOG) != 0) {
			throw SocketException();
		}
		_isListening = true;
	}
}

void TcpServer::listen(uint16_t port) {
	listen(SocketAddress(IpAddress::ANY, port));
}

bool TcpServer::isListening() const {
	return _isListening;
}

TcpSocket* TcpServer::accept() {
	if (!_isListening || _descriptor == 0) {
		return 0;
	}
	int sockfd = ::accept(_descriptor, 0, 0);
	if (sockfd == -1) {
		return 0;
	}
	return new TcpSocket(sockfd);
}

END_NAMESPACE_TOXIC
